import { Transaction } from 'tiny-entity2';
import { RouteOptionsBase } from './../../common/http/router/routeDecorators';
import { Guid } from './../../common/utils/guid';
import { Page, PageType } from './../../domain/models/page';
import { ServiceException } from './../../common/excpetion/serviceException';
import { ApiDataContext } from './../../domain/apiDataContext';
import { OrgPageItem } from './../../domain/models/orgPageItem';
import { PageService } from './../../service/pageService';
import { ServiceManager } from './../../common/serviceFactory/serviceManager';
import * as Koa from 'koa';
import { route, RouteOptionsVerify, UsingLock } from "../../common";
import { TemplateService } from '../../service/templateService';
import { ConditionService } from '../../service/conditionService';
import { DataSourceService } from '../../service/dataSourceService';
const pSvr = ServiceManager.Current.GetService<PageService>('PageService');
const tmpSvr = ServiceManager.Current.GetService<TemplateService>('TemplateService');
const conditionSvr = ServiceManager.Current.GetService<ConditionService>('ConditionService');
const dsSvr = ServiceManager.Current.GetService<DataSourceService>('DataSourceService');
class PageController {
    @route(new RouteOptionsBase('GET', '/api/page'))
    async queryPages(ctx: Koa.Context, next) {
        let p = ctx.query;
        ctx.response.body = await pSvr.QueryPage(p);
        await next();
    }
    @route(new RouteOptionsVerify('GET', '/api/page/:id'))
    async getPageInfoById(ctx: Koa.Context, next) {
        let { id } = ctx.params;
        let page = await pSvr.GetPageById(id);
        if (!page) {
            throw new ServiceException('当前page 不存在！', 'Page_Not_Exist');
        }
        page.pageTmpItems = await pSvr.GetPageTmpItemsByPageId(page.id);
        for (let item of page.pageTmpItems) {
            item.template = await tmpSvr.GetTemplateById(item.templateId);
        }

        page.pageTmpItems = page.pageTmpItems.filter(x => x.template);

        ctx.response.body = page;
        await next();
    }
    @route(new RouteOptionsVerify('POST', '/api/page'))
    async savePage(ctx: Koa.Context, next) {
        let orgId = ctx.headers['orgid'];
        let page: Page = ctx.request.body;
        page.orgId = orgId;
        if (!page.id) {
            throw new ServiceException('未传入id');
        }
        if (!page.name) {
            throw new ServiceException('未传入name');
        }
        if (!page.type) {
            throw new ServiceException('未传入type');
        }

        let has = await pSvr.GetPageById(page.id);

        await UsingLock(page.id, async () => {
            return await Transaction(new ApiDataContext(), async ctx => {
                if (has) {
                    await pSvr.UpdatePage(page, ctx);
                }
                else {
                    await pSvr.CreatePage(page, ctx);
                    let orgPageItem = new OrgPageItem();
                    orgPageItem.id = Guid.GetGuid();
                    orgPageItem.orgId = orgId;
                    orgPageItem.pageId = page.id;
                    await pSvr.CreateOrgPageItem(orgPageItem, ctx);
                }

                await tmpSvr.DeleteTemplateRefByPageId(page.id, ctx);

                for (let pitem of page.pageTmpItems) {
                    pitem.id = Guid.GetGuid();
                    pitem.pageId = page.id;
                    pitem.orgId = orgId;
                    if (!pitem.templateId) {
                        throw new ServiceException('templateId不能为空！');
                    }

                    await pSvr.CreatePageTmpItem(pitem, ctx);

                    if (pitem.template) {
                        pitem.template.id = pitem.templateId;
                        pitem.template.orgId = orgId;
                        let hasTmp = await tmpSvr.HasTemplate(pitem.templateId);
                        if (hasTmp) {
                            await tmpSvr.UpdateTemplate(pitem.template, ctx);
                        }
                        else {
                            await tmpSvr.CreateTemplate(pitem.template, ctx);
                        }

                        if (pitem.template.condition) {
                            await conditionSvr.DeleteCondition(pitem.template.condition.id, ctx);
                            pitem.template.condition.id = Guid.GetGuid();
                            pitem.template.condition.objectId = pitem.templateId;
                            pitem.template.condition.objectType = 'Template';
                            pitem.template.condition.orgId = orgId;

                            await conditionSvr.CreateCondition(pitem.template.condition, ctx);
                        }

                        for (let tmItem of pitem.template.tmpComItems) {
                            if (!tmItem.id) {
                                tmItem.id = Guid.GetGuid();
                            }

                            tmItem.templateId = pitem.templateId;
                            tmItem.orgId = orgId;
                            await tmpSvr.CreateTmpComItem(tmItem, ctx);

                            if (tmItem.condition) {
                                tmItem.condition.id = Guid.GetGuid();
                                tmItem.condition.objectId = tmItem.id;
                                tmItem.condition.objectType = 'TmpComItem';
                                tmItem.condition.orgId = orgId;
                                await conditionSvr.CreateCondition(tmItem.condition, ctx);
                            }
                        }
                    }
                }

            });
        })
        ctx.response.body = page;
        await next();
    }

    @route(new RouteOptionsVerify('PUT', '/api/page/:id/isDisable/:isDisable'))
    async updatePageDisable(ctx: Koa.Context, next) {
        let { id, isDisable } = ctx.params;

        let page = await pSvr.GetPageById(id);
        if (isDisable && isDisable == 'true') {
            page.isDisable = true;
        }
        else {
            page.isDisable = false;
        }
        await UsingLock(id, async () => {
            page.updateTime = Date.now();
            return await pSvr.UpdatePage(page);
        })
        ctx.response.body = page;
        await next();
    }

    @route(new RouteOptionsVerify('DELETE', '/api/page/:id'))
    async deletePage(ctx: Koa.Context, next) {
        let { id } = ctx.params;
        UsingLock(id, async () => {
            await pSvr.DeletePageById(id);
        })

        ctx.response.body = {};

        await next();
    }

    @route(new RouteOptionsVerify('post', '/api/orgPageItem/page/type/login'))
    async addLoginPage(ctx: Koa.Context, next) {
        let data: OrgPageItem = ctx.request.body;
        const orgId = ctx.headers['orgid'];
        if (!data.page) {
            throw new ServiceException('未传入page');
        }
        // if (!data.id) {
        //     throw new ServiceException('未传入id');
        // }
        if (!data.orgId) {
            throw new ServiceException('未传入orgId');
        }

        await UsingLock(data.id, async () => {
            return await Transaction(new ApiDataContext(), async ctx => {
                let loginPages = await pSvr.GetLoginPage(data.orgId);
                let loginPage: Page;
                if (loginPages.length) {
                    loginPage = loginPages[0].page;
                }

                data.page.name = '登录配置页面';

                if (loginPage) {
                    data.page.id = loginPage.id;
                    data.page.viewId = loginPage.viewId;
                    data.page.type = PageType.LoginPage;
                    data.page.orgId = orgId;
                    data.page = await pSvr.UpdatePage(data.page, ctx);
                }
                else {
                    data.page.id = Guid.GetGuid();
                    data.page.viewId = Date.now() + '';
                    data.page.type = PageType.LoginPage;
                    data.page.orgId = orgId;
                    data.page = await pSvr.CreatePage(data.page, ctx);
                    data.pageId = data.page.id;
                    await pSvr.CreateOrgPageItem(data, ctx);
                }

            })
        })

        ctx.response.body = data;
        await next();
    }
}